package com.cmf.myproject.service.security.realm;

import java.util.Objects;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.cmf.myproject.dal.mybatis.model.BossUser;
import com.cmf.myproject.service.security.authc.MallUsernamePasswordToken;
import com.cmf.myproject.service.security.dto.LoginUserInfo;
import com.cmf.myproject.service.system.sysrole.SysRoleService;
import com.cmf.myproject.service.system.user.BossUserService;


/**
 * Created by h.p on 2018/12/4.
 */
public class BossUserRealmImpl extends AuthorizingRealm {
    private static final Logger logger = LoggerFactory.getLogger(BossUserRealmImpl.class);

    private String supportedLoginType;

    @Autowired
    private BossUserService bossUserService;
    
    @Autowired
    private SysRoleService sysRoleService;

    /**
     * 权限
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        // 获取当前登陆用户
        Subject subject = SecurityUtils.getSubject();
        LoginUserInfo user = (LoginUserInfo) subject.getPrincipal();
        if(user.getUserName().equalsIgnoreCase("admin")) {
        	authorizationInfo.addRole("*");
            authorizationInfo.addStringPermission("*");
        } else {
        	sysRoleService.roleResourceList(user.getRoleId()).forEach((key,item)->{
        		authorizationInfo.addRole(key);
        		authorizationInfo.addStringPermissions(item);
        	});
        }
        return authorizationInfo;
    }

    /**
     * 认证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        logger.debug("boss user realm authentication:" + authenticationToken.toString());
        MallUsernamePasswordToken token = (MallUsernamePasswordToken)authenticationToken;

        BossUser bossUser = bossUserService.findByUsername(token.getUsername());
        if (Objects.isNull(bossUser)) {
            throw new UnknownAccountException();
        }
        if (bossUser.getIsLocked()) {
            throw new DisabledAccountException("user locked");
        }

        LoginUserInfo userInfo = new LoginUserInfo();
        userInfo.setId(bossUser.getId().toString());
        userInfo.setUserName(bossUser.getUserName());
        userInfo.setNickName(bossUser.getNick());
        userInfo.setType(token.getLoginType());
        userInfo.setRoleId(bossUser.getUserRoleId());
        /* 密码验证交给HashedCredentialsMatcher */
        AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
        		userInfo,
        		bossUser.getPassword(),
                getName());
        return authenticationInfo;
    }

    @Override
    public boolean supports(AuthenticationToken token){
        if (token instanceof MallUsernamePasswordToken) {
            MallUsernamePasswordToken usernamePasswordToken = (MallUsernamePasswordToken) token;
            return getSupportedLoginType().equals(usernamePasswordToken.getLoginType());
        }
        return false;
    }

    public String getSupportedLoginType() {
        return supportedLoginType;
    }

    public void setSupportedLoginType(String supportedLoginType) {
        this.supportedLoginType = supportedLoginType;
    }
}
